/*
 * Copyright 2001-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package code.buildit.plugin;

import code.buildit.plugin.adapter.PsiClassAdapter;
import code.buildit.plugin.configuration.Configuration;
import code.buildit.plugin.fileconfig.JavaFile;
import code.buildit.plugin.processor.CreateBuilderClassCommand;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiManager;

public class BuildItClassActionHandler extends EditorWriteActionHandler {

    public void executeWriteAction(Editor editor, DataContext dataContext) {
        process(editor.getProject());
    }

    public void process(Project project) {

        PsiJavaFile psiJavaFile = getCurrentJavaFile(project);
        if (psiJavaFile == null)
            return;

        VirtualFile virtualFile = psiJavaFile.getVirtualFile();
        if (virtualFile == null)
            return;
        String fileName = virtualFile.getNameWithoutExtension();

        toggleToBuilderClass(project, psiJavaFile, fileName);

    }

    private void toggleToBuilderClass(Project project, PsiJavaFile psiJavaFile, String fileName) {
        String toggledName = new JavaFile(psiJavaFile.getPackageName(), fileName).toggledName(new Configuration());

        PsiClass toggledClass = findPsiClass(toggledName, project);
        if (toggledClass == null) {
            createNewBuilderClass(psiJavaFile, toggledName);
            return;
        }

        toggledClass.navigate(true);
    }

    private PsiJavaFile getCurrentJavaFile(Project project) {
        PsiClass aClass = new PsiClassAdapter(project).getSelectedClass();
        PsiFile psiFile = aClass.getContainingFile();
        return (PsiJavaFile) psiFile;
    }

    private void createNewBuilderClass(PsiJavaFile psiJavaFile, String toggledName) {
        if (toggledName.contains(Configuration.BUILDER)) {
            PsiClass toggledClass = buildJavaFile(psiJavaFile.getClasses()[0], toggledName);
            if (toggledClass == null)
                return;

            new BuildItActionHandler().doExecuteAction(toggledClass, psiJavaFile.getClasses()[0].getAllFields(), true);
            toggledClass.navigate(true);

        }
    }

    private PsiClass buildJavaFile(PsiClass aClass, String toggledName) {
        CreateBuilderClassCommand createClassCommand =
                new CreateBuilderClassCommand(aClass, new JavaFile(toggledName));
        ApplicationManager.getApplication().runWriteAction(createClassCommand);
        return createClassCommand.getPsiClass();
    }

    private PsiClass findPsiClass(String name, Project project) {
        return new PsiClassAdapter(project).findPsiClassByName(project, PsiManager.getInstance(project), name);
    }

}
